package com.oauth.service.application.dao;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Required;

import com.oauth.service.application.beans.ApplicationServiceBean;
import com.oauth.service.application.beans.MemberApplicationRelation;
import com.oauth.service.jdosupport.PMF;

public class ApplicationDAOImpl implements ApplicationDAO,InitializingBean {

	private List<ApplicationServiceBean> applicationList = new ArrayList<ApplicationServiceBean>();
	
	private HashMap<Long,ApplicationServiceBean> applicationIdMap = new HashMap<Long, ApplicationServiceBean>();
	
	public ApplicationServiceBean addNewApplication(ApplicationServiceBean pApplicationServiceBean) {
		applicationIdMap.put(pApplicationServiceBean.getKey(),pApplicationServiceBean);
		return pApplicationServiceBean;
	}

	public ApplicationServiceBean getApplicationById(Long pApplicationId){
		return applicationIdMap.get(pApplicationId);
	}
	
	
	public List<ApplicationServiceBean> getApplicationList() {
		return applicationList;
	}

	@Required
	public void setApplicationList(List<ApplicationServiceBean> pApplicationList) {
		applicationList = pApplicationList;
	}

	public List<ApplicationServiceBean> getApplicationByIds(Collection<Long> pApplicationIds){
		List<ApplicationServiceBean> applicationList = new ArrayList<ApplicationServiceBean>();
		for(Long applicationId:pApplicationIds){
			if(applicationIdMap.containsKey(applicationId)){
				applicationList.add(applicationIdMap.get(applicationId));
			}
		}
		return applicationList;
	}
	public MemberApplicationRelation addMemberToApplication(Long pMemberId,Long pApplicationId) {
		PersistenceManager persistenceManager = PMF.get()
				.getPersistenceManager();
		MemberApplicationRelation memberApplications = null;
		try {
			memberApplications = getMemberApplications(pMemberId, persistenceManager);
			if( memberApplications == null){
				memberApplications = new MemberApplicationRelation(pMemberId,new HashSet<Long>());
			}
			
			memberApplications.addApplication(pApplicationId);

			memberApplications = persistenceManager
					.makePersistent(memberApplications);

		} finally {
			persistenceManager.close();
		}
		return memberApplications;
	}

	public List<Long> getUnSubscribedApplications(Long pMemberId){
		MemberApplicationRelation memberApplications = getMemberApplications(pMemberId);
		List<Long> unSubscribedIdList = new ArrayList<Long>();

		if (memberApplications == null || memberApplications.getApplicationIdSet().isEmpty()) {
			return new ArrayList<Long>(applicationIdMap.keySet());
		}
		Set<Long> subscribedIdSet = memberApplications
					.getApplicationIdSet();

		for (Long applicationId : applicationIdMap.keySet()) {
			if (subscribedIdSet.contains(applicationId) == false) {
				unSubscribedIdList.add(applicationId);
			}
		}
		return unSubscribedIdList;
	}
	
	public MemberApplicationRelation removeMemberToApplication(Long pMemberId,
			Long pApplicationId) {
		PersistenceManager persistenceManager = PMF.get()
				.getPersistenceManager();
		MemberApplicationRelation memberApplications = null;
		try {
			memberApplications = getMemberApplications(pMemberId,persistenceManager);
			if (memberApplications == null) {
				memberApplications = new MemberApplicationRelation(pMemberId,
						new HashSet<Long>(1));
			}

			memberApplications.removeApplication(pApplicationId);

			memberApplications = persistenceManager
					.makePersistent(memberApplications);

		} finally {
			persistenceManager.close();
		}
		return memberApplications;
	}

	
	public MemberApplicationRelation getMemberApplications(Long pMemberId) {
		PersistenceManager persistenceManager = PMF.get()
				.getPersistenceManager();
		try{
			return getMemberApplications(pMemberId, persistenceManager);
		}
		finally {
			persistenceManager.close();
		}
	}

	@SuppressWarnings("unchecked")
	private MemberApplicationRelation getMemberApplications(Long pMemberId,PersistenceManager pPersistanceManager){
		List<MemberApplicationRelation> results = null;

			Query query = pPersistanceManager
					.newQuery(MemberApplicationRelation.class);
			query.setFilter("memberId == memberIdParam");
			query.declareParameters("Long memberIdParam");
			results = (List<MemberApplicationRelation>) query
					.execute(pMemberId);
			if (results == null || results.isEmpty()) {
				return null;
			}
			return results.get(0);
	}
	
	@Override
	public void afterPropertiesSet() throws Exception {
		
		for(ApplicationServiceBean application:applicationList){
			addNewApplication(application);
		}
	}
}
